3 - Aufgabe 4: Threadumschaltung [ID:21396]
50 von 167 angezeigt

Bis jetzt hatten wir in unserem Stubs einen festen Faden pro CPU, haben also für jede

Anwendung einen Kern exklusiv verwendet.

Das wollen wir in dieser Aufgabe mittels kooperativen Scheduling so ändern, dass wir quasi beliebig

viele Anwendungen gleichzeitig laufen lassen können.

Im Beispiel laufen nun 9 Zähleranwendungen parallel.

Dabei wird in der Ausgabe für jeden Kern eine eigene Farbe verwendet, um das Durchwechseln

zu verdeutlichen.

Externe Geräte wie die Tastatur bleiben natürlich auch weiterhin aktiv.

Für die Umsetzung müssen wir nun erstmal down the rabbit hole und sowohl tiefer in

die x86 Architektur als auch die System5 API einarbeiten, um in Assembler einen Kontextwechsel

implementieren zu können.

Im Anschluss sollen die Anwendungen so umgebaut werden, dass diese als Threads in einem Scheduler

verwaltet werden können.

Diese Verwaltung soll im Ordner thread bereitgestellt werden.

Der systemnahe Kontextwechsel wird in machine implementiert.

Der Scheduler erlaubt Threads zur Ausführung dynamisch hinzuzufügen und wieder zu entfernen,

mittels einer Liste von Zeigern auf Thread-Objekten.

Mit graded-scheduler gibt es eine einfache Systemaufruf-Schnittstelle, damit dies auch

von Anwendungen selbst gesteuert werden kann, zum Beispiel das Beenden einer anderen Anwendung.

Die Anwendungen selbst sind von der Klasse thread abgeleitet und werden in der Methode

Action implementiert.

Diese Methode ist in thread als pure virtual deklariert, muss also zwingend in jeder Ableitung

implementiert werden.

Eine Anwendung, welche das erste Mal per Kontext-Switch eingelastet wird, soll ihre Ausführung bei

der Methode Action beginnen.

Wir bräuchten also die Adresse dieser Methode als Einsprungsfunktion, allerdings ist diese

Adresse gar nicht zu trivial zu ermitteln, wenn wir nur den Pointer zum thread-Objekt

haben.

Sie ist ein virtueller Member, die tatsächliche Adresse der Funktion wird also dynamisch zur

Laufzeit durch die V-Table der Tabelle virtueller Methoden ermittelt, abhängig von welcher

Anwendung das Objekt tatsächlich ist.

Und wie so eine V-Table aufgebaut ist, ist natürlich wieder nicht im C++-Standard spezifiziert,

sondern abhängig vom jeweiligen Übersetzer.

Wir wollen aber eine generische Lösung, versuchen also gar nicht erst selbst diese Struktur

nachzulaufen, sondern lassen den Übersetzer den entsprechenden Code generieren, mittels

der Hilfsfunktion kickoff.

Diese bekommt als Parameter den Zeiger auf den thread und ruft damit dann Action auf.

Der Übersetzer muss für diesen Aufruf in kickoff entsprechend selbst die Auflösung

mittels der V-Table einbauen.

Unsere Einsprungsfunktion ist somit nun also nicht die Methode Action selbst, sondern kickoff,

welches dann eben diese Methode aufruft.

Und entsprechend müssen wir auch den Stack vorbereiten, was wir über die Funktion prepareContext

erledigen.

Diese erhält als ersten Parameter die Adresse des topOfStack, also das oberer Ende des

jeweiligen Stacks.

Dazu soll für jeden thread ein 4096 byte großer Speicher reserviert werden.

Der zweite Parameter ist der Funktionszeiger zur eben erwähnten kickoff-Funktion, welcher

mit den in param spezifizierten Parameter aufgerufen wird.

Der Rückkabewert ist die Adresse des letzten Eintrags, die auf diesem Stack hinzugefügt

wurde, somit also der initiale Stackpointer für den thread.

Teil einer Videoserie :
Teil eines Kapitels:
Threadumschaltung

Zugänglich über

Offener Zugang

Dauer

00:12:09 Min

Aufnahmedatum

2020-08-12

Hochgeladen am

2020-10-16 18:36:33

Sprache

de-DE

Tags

betriebssysteme operating systems stubs
Einbetten
Wordpress FAU Plugin
iFrame
Teilen